from llvmlite import ir

from .base import BuiltinFunction, get_builtin_function_cls
from MelodieAllegro.types import integer, double, string


class PMZeroArray(BuiltinFunction):
    def register(self):
        func_ty = ir.FunctionType(ir.PointerType(ir.IntType(8)), [integer])
        self.func = ir.Function(self.module, func_ty, name="create_zero_array")
        builder = ir.IRBuilder(self.func.append_basic_block('entry'))

    def __call__(self, builder, args=None, arg_types=None, name=''):
        from ...types import PMArrayType, integer
        assert isinstance(args, list)
        assert len(args) == 2
        length = args[0]
        typ = args[1]
        assert length.type == integer
        typ = PMArrayType(integer)
        return typ.create_by_var(builder, length, name), typ


# class NewIntegerSet(BuiltinFunction):
#     def register(self):
#         func_ty = ir.FunctionType(ir.PointerType(integer), [])
#         self.func = ir.Function(self.module, func_ty, name="pm_intset_create")
#
#     def __call__(self, builder: ir.IRBuilder, name=""):
#         return builder.call(self.func, [], name=name)
#
#
# class AddToIntegerSet(BuiltinFunction):
#     def register(self):
#         func_ty = ir.FunctionType(ir.VoidType(), [ir.PointerType(integer), integer])
#         self.func = ir.Function(self.module, func_ty, name="pm_intset_add")
#
#     def __call__(self, builder: ir.IRBuilder, set_obj, value, name=""):
#         assert value.type == integer
#         return builder.call(self.func, [set_obj, value], name=name)
#
#
# class ShowIntegerSetElements(BuiltinFunction):
#     def register(self):
#         func_ty = ir.FunctionType(ir.VoidType(), [ir.PointerType(integer)])
#         self.func = ir.Function(self.module, func_ty, name="pm_intset_show")
#
#     def __call__(self, builder: ir.IRBuilder, set_obj, name=""):
#         return builder.call(self.func, [set_obj], name=name)
#
#
# class IntegerSetHasElement(BuiltinFunction):
#     def register(self):
#         func_ty = ir.FunctionType(integer, [ir.PointerType(integer), integer])
#         self.func = ir.Function(self.module, func_ty, name="pm_intset_has")
#
#     def __call__(self, builder: ir.IRBuilder, set_obj, elem, name=""):
#         return builder.call(self.func, [set_obj, elem], name=name)
#
#
# class IntegerSetFree(BuiltinFunction):
#     def register(self):
#         func_ty = ir.FunctionType(ir.VoidType(), [ir.PointerType(integer)])
#         self.func = ir.Function(self.module, func_ty, name="pm_intset_free")
#
#     def __call__(self, builder: ir.IRBuilder, set_obj, name=""):
#         return builder.call(self.func, [set_obj], name=name)
#
#
# class IntegerSetToBuffer(BuiltinFunction):
#     def register(self):
#         func_ty = ir.FunctionType(ir.PointerType(integer), [ir.PointerType(integer)])
#         self.func = ir.Function(self.module, func_ty, name="pm_intset_to_buffer")
#
#     def __call__(self, builder: ir.IRBuilder, set_obj, name=""):
#         return builder.call(self.func, [set_obj], name=name)


builtin_container_funcs = get_builtin_function_cls(globals())
